package com.vhall.component.framework.oss.client.impl.qcloud;

import cn.hutool.core.lang.Assert;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.vhall.component.framework.common.utils.StringUtils;
import com.vhall.component.framework.oss.client.OssResult;
import com.vhall.component.framework.oss.client.impl.AbstractOssClient;
import com.vhall.component.framework.oss.properties.OssProperties;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;

/**
 * 腾讯云 COS 实现
 *
 * @author yongzheng.xu
 * @date 2021/5/22 21:47
 */
@Slf4j
public class QCloudClient extends AbstractOssClient {


    /**
     * 阿里云客户端
     */
    private volatile COSClient client;


    public QCloudClient(OssProperties properties) {
        super(properties, new QCloudCodeMapping());
        Assert.notEmpty(properties.getAppId(), "secretId 不能为空");
        Assert.notEmpty(properties.getSecretKey(), "secretKey 不能为空");
    }

    @Override
    protected void doInit() {
        ClientConfig cc = new ClientConfig();
        Region region = new Region(properties.getRegion());
        cc.setRegion(region);
        COSCredentials cd = new BasicCOSCredentials(properties.getAppId(), properties.getSecretKey());
        client = new COSClient(cd, cc);
    }

    @Override
    protected OssResult<String> doUpload(String name, String contentType, InputStream stream) throws IOException {
        try {
            // 指定文件上传到 COS 上的路径，即对象键。例如对象键为folder/picture.jpg，
            // 则表示将文件 picture.jpg 上传到 folder 路径下
            String key = name;
            if (StringUtils.isNotEmpty(properties.getPrefix())) {
                key = properties.getPrefix() + "/" + name;
            }

            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(stream.available());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentType(contentType);
            metadata.setContentDisposition("inline;filename=" + name);

            // 指定上传文件操作时是否覆盖同名Object。
            // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
            // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
            // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
            metadata.setHeader("x-oss-forbid-overwrite", "false");

            PutObjectRequest request = new PutObjectRequest(properties.getBucket(), key, stream, metadata);
            //上传文件
            PutObjectResult result = client.putObject(request);
            // 封装  url 路径
            String url = "https://" + properties.getBucket() + "." + properties.getFullRegion() + "/" + key;
            String cdnRegion = properties.getCdnRegion();
            if (org.apache.commons.lang3.StringUtils.isNotBlank(cdnRegion)) {
                url = "https://" + cdnRegion + "/" + key;
            }
            return OssResult.build("200", "success", result.getRequestId(), url, codeMapping);
        } catch (CosServiceException ex) {
            log.error("上传QCloud COS失败:", ex);
            return OssResult.build(ex.getErrorCode(),
                    ex.getErrorMessage(),
                    ex.getRequestId(),
                    "",
                    codeMapping);

        }
    }
}
